﻿using gt.rediscache.logger;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

namespace gt.rediscache.plugins
{
    /// <summary>
    /// redisclient state 报告
    /// </summary>
    public class RedisClientStateReporter<TReportInfo>
        where TReportInfo : class
    {
        private string _reportApi;
        private ConcurrentQueue<TReportInfo> _queue;

        public RedisClientStateReporter()
        {
            _queue = new ConcurrentQueue<TReportInfo>();
            Start();
        }

        public void SetReportApi(string api)
        {
            _reportApi = api;
        }

        public void ReportAsync(TReportInfo info)
        {
            if (string.IsNullOrEmpty(_reportApi)) return;
            if (info == null) return;
            if (_queue.Count > 1000) return;
            _queue.Enqueue(info);
        }

        private void Start()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        TReportInfo clientInfo = null;
                        if (_queue.TryDequeue(out clientInfo))
                        {
                            if (clientInfo != null)
                                SendRedisCacheInfoAsync(clientInfo);
                        }
                        else
                            System.Threading.Thread.Sleep(10000);
                    }
                    catch { }
                }
            });
            RedisLogManager.Info("reportIhandler thread work start ok!");
        }

        private void SendRedisCacheInfoAsync(TReportInfo info)
        {
            Task.Run(() =>
            {
                try
                {
                    string result = HttpClientUtility.Post(_reportApi, JsonConvert.SerializeObject(info));
                }
                catch (Exception ex)
                {
                    RedisLogManager.Error(string.Format("redisclient  info report error:{0}", ex.Message + ex.StackTrace));
                }
            });
        }
    }
}
